import json

from pydantic.v1 import BaseSettings, validator


class DbConfig(BaseSettings):
    host: str
    port: int
    name: str
    user: str
    password: str
    echo: bool = False

    def full_url(self, with_driver: bool = True) -> str:
        login_data = f"{self.user}:{self.password}@{self.host}:{self.port}/{self.name}"
        if with_driver:
            return f"postgresql+asyncpg://{login_data}"
        return f"postgresql://{login_data}"


class RedisConfig(BaseSettings):
    host: str
    port: int
    database: int

    @property
    def url(self) -> str:
        return f"redis://@{self.host}:{self.port}/{self.database}"


class PaymentConfig(BaseSettings):
    terminal_key: str
    password: str


class TgBot(BaseSettings):
    token: str
    admin_ids: list[int]
    use_redis: bool

    @validator("admin_ids", pre=True, always=True)
    def admin_ids_list(cls, v) -> list[int]:
        return json.loads(v)


class Settings(BaseSettings):
    tg_bot: TgBot
    db: DbConfig
    redis: RedisConfig
    payment: PaymentConfig

    class Config:
        env_file = ".env"
        env_file_encoding = "utf-8"
        env_nested_delimiter = "__"


def load_config(env_file=".env.dev") -> Settings:
    settings = Settings(_env_file=env_file)
    return settings
